/**
 * @file executionObj.h
 * @brief Header che contiene le dichiarazioni delle strutture
 * e delle funzioni per gli oggetti utilizzati per l'esecuzione.
 *
 * Sono stati dichiarati in questo header le strutture per le interfacce dei comandi
 * e delle richieste. L'header include @see userparam.h per importare l'oggetto UserParam
 * utilizzato nelle richieste.
 *
 *
 * @date Mar 24, 2012
 * @author Francesco Corvino
 */

#ifndef EXECUTIONOBJ_H_
#define EXECUTIONOBJ_H_
#include "userparam.h"
#include "../RscHost/session.h"

#define COMMAND_NAMEDLOG "command"
#define REQUEST_NAMEDLOG "request"

/**
 * @brief Descrizione di un comando.
 *
 * Rappresenta l'interfaccia Command del pattern, tutti i ConcreteCommand devono poter
 * essere adattati a questa struttura definendo una loro funzione <code>void execute()</code>.
 */
typedef struct interfaceCommand {
	// campi obbligatori

	/**
	 * @brief identificativo del comando.
	 */
	char *name;

	/**
	 * @brief funzione da eseguire sull'invocazione.
	 */
	void (*execute)();

	// campi opzionali
	HiddenType descriptorInfo;
	HiddenType typeCommand;
} InterfaceCommand;

/**
 * @brief Struttura che permette di definire in maniera più semplice un comando.
 */
typedef struct simpleDescCommand {
	char *namecmd; /**< nome del comando */
	char *helpstr; /**< stringa che verrà stampata nell'help */
	void (*execfnc)(void); /**< funzione da eseguire */
} SimpleDescCommand;

/**
 * @brief Descrizione di una richiesta da parte dell'utente.
 *
 * La richiesta non rappresenta ancora un comando, un'utente può utilizzare diversi modi
 * per richiedere un'esecuzione. In base alle politiche adottate per interfacciarsi con l'utente
 *  si possono definire ulteriori argomenti in questa struttura.
 *
 */
typedef struct userRequest {
	/**
	 * @brief attributo che specifica il nome del comando da invocare.
	 */
	char *nameCmd;

	/**
	 * @brief riassume l'invocazione da linea di comando effettuata dall'utente.
	 */
	char *linereq;

	/**
	 * @brief array dinamico per inserire i vari parametri ricavati dalle specifiche dell'utente.
	 */
	DynArray params;

	/**
	 * @brief sessione a cui viene assegnato lo svolgimento della richiesta.
	 */
	HostSession * session;

	/**
	 * @brief puntatore al comando individuato.
	 */
	InterfaceCommand * command;
} UserRequest;

//////////////////////////////////////////////////////////////////////////////////
////// funzioni per la gestione delle richieste //////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////

/**
 * @brief Inizializza la struttura dati UserRequest ricavando gli attributi
 * principali dalla linea (stringa ricavata dall'input) immessa dall'utente.
 */
void UserRequest_init(UserRequest * req, char* linereq);

/**
 * @brief Elimina gli spazi di memoria allocati per una richiesta.
 */
void UserRequest_destroy(UserRequest * req);

/**
 * @brief Funzione che permette di confrontare due richieste in base alla sessione.
 *
 * @param a
 * @param b
 * @return il confronto tra i valori delle sessioni.
 */
int UserRequest_cmpBySession(const void * a, const void * b);

//////////////////////////////////////////////////////////////////////////////////
////// funzioni per definire nuovi commandi e registrarli  ///////////////////////
//////////////////////////////////////////////////////////////////////////////////

void Command_initBySimpleDef(InterfaceCommand *cmd, SimpleDescCommand *scmd);

void Command_initSimple(InterfaceCommand * cmd, char* name, void (*execute)());

void Command_initComplete(InterfaceCommand * cmd, char* name, void (*execute)(),
		HiddenType *info, HiddenType *type);

InterfaceCommand * Command_getDefault();

void Command_destroy(const void * cmdelem);

int Command_cmp(const void * a,const void * b);

InterfaceCommand * Command_get(DynArray *commands, char *name);

#endif /* EXECUTIONOBJ_H_ */
